package org.weso.desempleo.model;

import java.util.LinkedList;
import java.util.List;

import org.weso.desempleo.services.to.ListConcejoStatsTO;
import org.weso.desempleo.to.ConcejoStatsTO;

import com.hp.hpl.jena.query.QueryExecution;
import com.hp.hpl.jena.query.QuerySolution;
import com.hp.hpl.jena.query.ResultSet;

public class ChargerConcejo extends Charger<ListConcejoStatsTO, ConcejoStatsTO> {
	
	private List<Council> councils = null;
	
	public ChargerConcejo() {
		if(months[0][0] == null)
			initializeMonths();
		councils = new LinkedList<Council>();
	}

	@Override
	public ListConcejoStatsTO obtain(String lang, String anyo, 
			String month, String selector, String langAnt) {	
		String query = prepareSparqlQuery(anyo, selector, month, lang);
		QueryExecution qExec = initializeQuery("http://156.35.31.156/sparql", 
				query);
		processCouncils(qExec.execSelect());
		query = prepareDBPediaQuery(lang);
		 qExec = initializeQuery("http://dbpedia.org/sparql", 
				query);
		ListConcejoStatsTO concejos = (ListConcejoStatsTO)
				processResult(qExec.execSelect());
		return concejos;
	}

	@Override
	public ConcejoStatsTO extractData(QuerySolution sol, int observaciones) {
		String dataset = "Desempleo por concejos en los meses de Junio, " +
				"Julio y Agosto de 2011 en el Principado de Asturias";
		String type = "Observations";
		String population = sol.get("population").toString();
		population = population.substring(0, population.indexOf("^^"));
		String homepage = sol.get("homepage").toString();
		String point = sol.get("point").toString();
		point = (point.substring(0, point.lastIndexOf("@"))).replace(" ", ", ");
		String label = sol.get("label").toString();
		label = label.substring(0, label.lastIndexOf("@"));
		String comment = sol.get("comment").toString();
		comment = (comment.substring(0, comment.lastIndexOf("@"))).replace('"', ' ');
		int pos = findCouncil(label);
		ConcejoStatsTO concejo = null;
		if(pos != -1) {
			Council c = councils.get(pos);
			int unemploymentJune = Integer.parseInt(c.getUnemployment("2011-06"));
			int unemploymentJuly = Integer.parseInt(c.getUnemployment("2011-07"));
			int unemploymentAugust = Integer.parseInt(c.getUnemployment("2011-08"));
			concejo = new ConcejoStatsTO(label, dataset, 2011, 
					unemploymentJune, label, type, comment, 
					Integer.valueOf(population).intValue(), homepage, point, 
					unemploymentJuly, unemploymentAugust);
		}else {
			concejo = new ConcejoStatsTO(label, dataset, 2011, 0, label, 
					type, comment, 0, homepage, point, 0, 0);
		}
		return concejo;
	}

	@Override
	public ListConcejoStatsTO processResult(ResultSet result) {
		ListConcejoStatsTO concejos = new ListConcejoStatsTO();
		int observaciones = 1;
		while(result.hasNext()) {
			ConcejoStatsTO concejo = (ConcejoStatsTO)
					extractData(result.next(), observaciones);
			observaciones++;
			concejos.add(concejo);
		}
		return concejos;
	}
	
	public void processCouncils(ResultSet result) {
		while(result.hasNext()) {			
			obtainCouncils(result.next());
		}
	}

	@Override
	public String prepareSparqlQuery(String anyo, String selector,
			String month, String lang) {
		String query = "PREFIX o: <http://purl.org/observatory/observatory.owl#>\n";
		query += "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n";
		query += "SELECT ?council ?period ?unemployment\n";
		query += "FROM <http://purl.org/weso/testObservatory/observatoryByCouncil/>\n";
		query += "WHERE{\n";
		query += "?x rdf:type <http://purl.org/linked-data/cube#Observation>;\n";
		query += "o:refCouncil ?council;\n";
		query += "o:unemployment ?unemployment;\n";
		query += "o:refPeriod ?period}";
		return query;
	}	
	
	private void obtainCouncils(QuerySolution sol) {
		String council = sol.get("council").toString();
		String period = sol.get("period").toString();
		String unemployment = sol.get("unemployment").toString();
		if(!councils.contains(new Council(council))) {
			Council c = new Council(council);
			c.add(period, unemployment);
			councils.add(c);
		}else{
			Council c = councils.get(findCouncil(council));
			c.add(period, unemployment);
		}
	}
	
	private int findCouncil(String council) {
		for (int i = 0; i <councils.size(); i++) {
			Council c = councils.get(i);
			if(c.getLabel().equals(council) 
					|| c.getLabel().contains(council) 
					|| council.contains(c.getLabel())) {
				return i;
			}
		}
		return -1;
	}
	
	private String prepareDBPediaQuery(String lang) {
		String query = "PREFIX owl: <http://www.w3.org/2002/07/owl#>\n";
		query += "PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>\n";
		query += "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n";
		query += "PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n";
		query += "PREFIX foaf: <http://xmlns.com/foaf/0.1/>\n";
		query += "PREFIX dc: <http://purl.org/dc/elements/1.1/>\n";
		query += "PREFIX : <http://dbpedia.org/resource/>\n";
		query += "PREFIX dbpedia2: <http://dbpedia.org/property/>\n";
		query += "PREFIX dbpedia: <http://dbpedia.org/>\n";
		query += "PREFIX skos: <http://www.w3.org/2004/02/skos/core#>\n";
		query += "PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>\n";
		query += "PREFIX grs: <http://www.georss.org/georss/>\n";
		query += "SELECT ?population ?point ?label ?comment ?homepage\n";
		query += "FROM <http://dbpedia.org>\n";
		query += "WHERE {\n";
		query += "?x rdf:type <http://dbpedia.org/class/yago/MunicipalitiesInAsturias>;\n";
		query += "grs:point ?point;\n";
		query += "foaf:homepage ?homepage;\n";
		query += "dbpedia-owl:populationTotal ?population;\n";
		query += "rdfs:label ?label;\n";
		query += "rdfs:comment ?comment\n";
		query += "FILTER langMatches(lang(?label) , \"" + lang + "\")";
		query += "FILTER langMatches(lang(?comment) , \"" + lang + "\")}";
		return query;
	}

}
